﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using Labthink.PCSoft.UniversalHost4.Utility;
using NLog;

namespace Labthink.PCSoft.UniversalHost4.UserControls
{
    public class NotifyManager
    {
        private static readonly Dictionary<string, List<FrmNotify>> Notifies = new Dictionary<string, List<FrmNotify>>();

        private static readonly Dictionary<string, NotifyManager> Managers = new Dictionary<string, NotifyManager>();

        private readonly Window _owner;

        private readonly Logger _logger = LogManager.GetCurrentClassLogger();

        public static NotifyManager InstanceManager(Window owner)
        {
            if (owner is null)
            {
                return null;
            }

            if (!Managers.ContainsKey(owner.Name))
            {
                Managers.Add(owner.Name, new NotifyManager(owner));
            }

            return Managers[owner.Name];
        }

        public static NotifyManager InstanceManager(DependencyObject o)
        {
            var owner = Window.GetWindow(o);
            if (!Managers.ContainsKey(owner.Name))
            {
                Managers.Add(owner.Name, new NotifyManager(owner));
            }

            return Managers[owner.Name];
        }

        private NotifyManager(Window owner)
        {
            _owner = owner;
            if (!Notifies.ContainsKey(_owner.Name))
            {
                _owner.Closing += _owner_Closing;
                Notifies.Add(_owner.Name, new List<FrmNotify>());
            }
        }

        private void _owner_Closing(object sender, EventArgs e)
        {
            try
            {
                if (!(sender is Window w)) return;
                if (Notifies.ContainsKey(w.Name))
                {
                    var ns = Notifies[w.Name];
                    ns.Clear();
                    Notifies.Remove(w.Name);
                }

                if (Managers.ContainsKey(w.Name))
                {
                    Managers.Remove(w.Name);
                }
            }
            catch
            {
            }
        }

        public void ShowSuccess(string content, int? time = null, bool? closeOwner = false)
        {
            if (!time.HasValue) time = 2;
            Show(content, time, NotifyType.Success, closeOwner);
        }

        public void ShowAlarm(string content, int? time = null)
        {
            if (!time.HasValue) time = 3;
            Show(content, time, NotifyType.Alarm);
        }

        public void ShowError(string content, int? time = null)
        {
            if (!time.HasValue) time = 5;
            Show(content, time, NotifyType.Error);
        }

        private void Show(string content, int? time = null, NotifyType notify = NotifyType.Default,
            bool? closeOwner = false)
        {
            Application.Current.Dispatcher.Invoke(() =>
            {
                {
                    var frm = new FrmNotify
                    {
                        ContentStr = content,
                        NotifyType = notify,
                        CloseOwner = closeOwner
                    };

                    if (time.HasValue) frm.Time = time.Value;
                    frm.Width = _owner.ActualWidth * 0.8;
                    frm.Closed += Frm_Closed;
                    frm.Left = (_owner.ActualWidth - frm.Width) / 2 + _owner.Left;
                    frm.Top = _owner.Top + 40;
                    _logger.Trace("owner.ActualWidth: "+_owner.ActualWidth);
                    _logger.Trace("frm.Width: "+frm.Width);
                    _logger.Trace("_owner.Left: "+_owner.Left);
                    _logger.Trace("frm.Top: "+frm.Top);

                    if (!Notifies.ContainsKey(_owner.Name))
                    {
                        //return;
                        _owner.Closing += _owner_Closing;
                        Notifies.Add(_owner.Name, new List<FrmNotify>());
                    }

                    var last = Notifies[_owner.Name].LastOrDefault();
                    if (last != null) frm.Top = last.Top + 45;
                    Notifies[_owner.Name].Add(frm);
                    frm.Show(_owner);
                }
            });
        }

        private void Frm_Closed(object sender, EventArgs e)
        {
            try
            {
                var frm = sender as FrmNotify;
                if (!Notifies.ContainsKey(_owner.Name)) return;
                Notifies[_owner.Name].Remove(frm);
                if (frm.CloseOwner.HasValue && frm.CloseOwner.Value)
                {
                    _owner?.Close();
                }
            }
            catch (Exception exception)
            {
              
            }
        }
    }

    public enum NotifyType
    {
        Default,
        Success,
        Alarm,
        Error
    }
}
